package cn.thoughtworks.school.programCenter.services;

import cn.thoughtworks.school.programCenter.entities.Assignment;
import cn.thoughtworks.school.programCenter.entities.QuizNote;
import cn.thoughtworks.school.programCenter.entities.Task;
import cn.thoughtworks.school.programCenter.exceptions.BusinessException;
import cn.thoughtworks.school.programCenter.repositories.QuizNoteRepository;
import cn.thoughtworks.school.programCenter.repositories.TaskRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class QuizNoteService {
    @Autowired
    private QuizNoteRepository quizNoteRepository;
    @Autowired
    private TaskRepository taskRepository;
    @Autowired
    private UserCenterService userCenterService;
    @Autowired
    private AssignmentService assignmentService;

    public void addNoteToQuiz(QuizNote quizNote) {
        quizNoteRepository.save(quizNote);
    }

    public List<Map> getMyNotes(Long tutorId, Long programId) {
        List<QuizNote> myNotes = getNotesByUserIdAndProgramId(tutorId, programId);

        List<Map> students = getStudentsOfNotes(myNotes);
        List<Task> tasks = getTasksOfNotes(myNotes);
        List<Assignment> assignments = getAssignmentsOfNotes(myNotes);

        return myNotes.stream().map(myNote -> {
            Map temp = new HashMap();
            temp.put("taskTitle", getTaskTitle(tasks, myNote));
            temp.put("assignmentTitle", getAssignmentTitle(assignments, myNote));
            temp.put("studentName", getStudentName(students, myNote));
            temp.put("quizType", myNote.getQuizType());
            temp.put("programId", myNote.getProgramId());
            temp.put("taskId", myNote.getTaskId());
            temp.put("studentId", myNote.getStudentId());
            temp.put("assignmentId", myNote.getAssignmentId());
            temp.put("quizId", myNote.getQuizId());
            temp.put("noteContent", myNote.getNoteContent());
            temp.put("id", myNote.getId());
            return temp;
        }).collect(Collectors.toList());
    }

    public List<QuizNote> getNotesByUserIdAndProgramId(Long userId, Long programId) {
        return quizNoteRepository.findAllByTutorIdAndProgramId(userId, programId);
    }

    public List getStudentsOfNotes(List<QuizNote> notes) {
        List<Long> studentIdList = notes.stream().map(QuizNote::getStudentId).collect(Collectors.toList());
        String studentIds = studentIdList.stream().map(Object::toString).collect(Collectors.joining(","));
        return userCenterService.getUsersByIds(studentIds);
    }

    public List<Task> getTasksOfNotes(List<QuizNote> notes) {
        List<Long> taskIdList = notes.stream().map(QuizNote::getTaskId).collect(Collectors.toList());
        return taskRepository.getTasksByIdIn(taskIdList);
    }

    public List getAssignmentsOfNotes(List<QuizNote> notes) {
        List<Long> assignmentIdList = notes.stream().map(QuizNote::getAssignmentId).collect(Collectors.toList());
        return assignmentService.getAssignmentsByIds(assignmentIdList);
    }

    public String getStudentName(List<Map> students, QuizNote note) {
        return students.stream()
                .filter(student -> student.get("id").equals(Math.toIntExact(note.getStudentId())))
                .findFirst().get().get("username").toString();
    }

    public String getTaskTitle(List<Task> tasks, QuizNote note) {
        return tasks.stream()
                .filter(task -> task.getId().equals(note.getTaskId()))
                .findFirst().get().getTitle();
    }

    public String getAssignmentTitle(List<Assignment> assignments, QuizNote note) {
        return assignments.stream()
                .filter(assignment -> assignment.getId().equals(note.getAssignmentId()))
                .findFirst().get().getTitle();
    }

    public void deleteNoteById(Long noteId) throws BusinessException {
        QuizNote note = quizNoteRepository.findById(noteId).orElseThrow(() -> new BusinessException("Current note is not exist"));
        quizNoteRepository.delete(note);
    }
}
